package com.hpq.user.service.impl;

import com.hpq.common.event.UserRegisterEvent;
import com.hpq.common.utils.AssertUtil;
import com.hpq.user.dao.ItemBagDAO;
import com.hpq.user.dao.UserBackpackDAO;
import com.hpq.user.dao.UserDAO;
import com.hpq.user.domain.dto.UserLoginDTO;
import com.hpq.user.domain.enums.ItemEnum;
import com.hpq.user.domain.enums.ItemTypeEnum;
import com.hpq.user.domain.model.ItemBag;
import com.hpq.user.domain.model.User;
import com.hpq.user.domain.model.UserBackpack;
import com.hpq.user.domain.vo.response.user.UserBadgesResp;
import com.hpq.user.domain.vo.response.user.UserInfoResp;
import com.hpq.user.service.UserService;
import com.hpq.user.service.adapter.UserAdapter;
import com.hpq.user.service.cache.ItemCache;
import com.hpq.user.service.cache.UserCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserCache userCache;
    @Autowired
    private UserDAO userDao;
    @Autowired
    private UserBackpackDAO userBackpackDao;
    @Autowired
    private ItemCache itemCache;
    @Autowired
    private ItemBagDAO itemBagDao;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;


    /**
     *  获取用户信息
     * @param uid
     * @return
     */
    @Override
    public UserInfoResp getUserInfo(Long uid) {
        User userInfo = userCache.getUserInfo(uid);
        Integer modifyNameChance = userBackpackDao.getCountByValidItemId(uid, ItemEnum.MODIFY_NAME_CARD.getId());
        return UserAdapter.buildUserInfoResp(userInfo, modifyNameChance);
    }

    @Override
    public User login(UserLoginDTO userLoginDTO) {

        return null;
    }

    /**
     * 注册用户
     *
     * @param userSave
     * @return
     */
    @Override
    @Transactional // 开启事务 如果方法执行过程中发生异常，事务将被回滚；如果方法正常完成，事务将被提交。这确保了数据操作的原子性和一致性
    public void register(User userSave) {
         userDao.save(userSave);
        //todo 用户注册的事件
        applicationEventPublisher.publishEvent(new UserRegisterEvent(this,userSave));
    }

    /**
     *  修改用户名
     * @param uid
     * @param name
     */
    @Override
    @Transactional(rollbackFor = Exception.class ) //两次对数据库进行操作，如果其中一个失败，则全部回滚
    public void modifyName(Long uid, String name) {
        User OldUser = userDao.getByName(name);
        //判断用户名是否重复
        AssertUtil.isNotEmpty(OldUser, "用户名已存在,请换一个名字!");
        //获取改名卡
        UserBackpack modifyNameItem = userBackpackDao.getValidItemById(uid,ItemEnum.MODIFY_NAME_CARD.getId());
        AssertUtil.isNotEmpty(modifyNameItem, "改名卡不足!");
        //使用改名卡
        boolean success = userBackpackDao.updateItem(modifyNameItem);
        if(success){
            //修改用户名
            userDao.modifyName(uid,name);
        }
    }

    /**
     *  获取徽章列表
     * @param uid
     * @return
     */
    @Override
    public List<UserBadgesResp> getBadges(Long uid) {
        //获取所有徽章
        List<ItemBag> itemBags = itemCache.getByType(ItemTypeEnum.BADGE.getType());
        List<Long> itemIds = itemBags.stream().map(ItemBag::getId).collect(Collectors.toList());
        //获取用户所有徽章
        List<UserBackpack> userBadges = userBackpackDao.getBadgesByItemId(uid, itemIds);
        //查询用户佩戴的徽章
        User user = userDao.getById(uid);
        return UserAdapter.buildUserBadgesResp(itemBags, userBadges, user);
    }

    /**
     *  佩戴徽章
     * @param uid
     * @param itemId
     */
    @Override
    public void wearBadge(Long uid, Long itemId) {
        //确保背包有物品
        UserBackpack validItem = userBackpackDao.getValidItemById(uid, itemId);
        AssertUtil.isEmpty(validItem, "背包中没有该物品!");
        //确保物品是徽章
        ItemBag item = itemBagDao.getById(validItem.getItemId());
        AssertUtil.isNotEqual(item.getType(),ItemTypeEnum.BADGE.getType(),"该物品不是徽章，无法佩戴！");
        //佩戴徽章
        userDao.wearingBadge(uid,itemId);


    }
}
